<?php
require_once 'SpotLight/core/view/simple_html_dom.php';

class Response {
   
   private $elementsById = array ();
   private $elementsByTagName = array ();
   private $attributesByTagName = array ();
   
   private $jsEvals;
   
   private $contentTypeArray = array ('html' => 'text/html', 'xml' => 'text/xml', 'rss' => 'text/xml', 'file' => 'application/octet-stream' );
   private $contentType = 'xml'; //'text/xml'
   private static $instance = null;
   /*
   private $contentLength;
   private $filename;
   private $fileContent;
   */

   private $onLoadAction = false;
   
   private function __construct() {
      $this->elementsById = array ();
      $this->jsEvals = array ();
      $this->tmpl = '';
   }
   
   public static function getInstance() {
      if (self::$instance == null)
         self::$instance = new Response ( );
      return self::$instance;
   }
   
   /**
    * Set Response node (for ajax request)
    *
    * @param String $key #id of html element to replace
    * @param String (HTML) $val HTML to replace in #$key element
    */
   public function set($key, $val) {
      $this->elementsById [$key] = $val;
   }
   
   public function setElementById($key, $val) {
      $this->set ( $key, $val );
   }
   
   public function setAttributeBySelector($tagname, $key, $val) {
      $this->attributesByTagName [$tagname] = array (0 => $key, 1 => $val );
   }
   
   public function setElementByTagName($key, $val) {
      $this->elementsByTagName [$key] = $val;
   }
   
   public function addJSEval($val) {
      $this->jsEvals [] = $val;
   }
   
   public function append($key, $val) {
      if (array_key_exists ( $key, $this->elementsById ))
         $this->elementsById [$key] .= $val;
      else
         $this->elementsById [$key] = $val;
   }
   
   public function prepend($key, $val = '') {
      if (array_key_exists ( $key, $this->elementsById ))
         $this->elementsById [$key] = $val . $this->elementsById [$key];
      else
         $this->elementsById [$key] = $val;
   }
   
   public function get($key) {
      return array_key_exists ( $key, $this->elementsById ) ? $this->elementsById [$key] : null;
   }
   
   /**
    * @return unknown
    */
   public function getContentType() {
      return $this->contentType;
   }
   /**
    * @deprecated 
    *
    * @param unknown_type $type
    * @return unknown
    */
   public function responceIs($type) {
      return $this->contentType == $type;
   }
   
   /**
    * @param unknown_type $contentType
    */
   public function setContentType($contentType = 'xml') {
      $this->contentType = $contentType; //$this->contentTypeArray [$contentType];
   }
   
   
   public function setOnLoadAction() {
      $this->onLoadAction = true;
   }
   
   public function isOnLoadAction() {
      return $this->onLoadAction;
   }
   
   /**
    * Generate responce
    *
    * @return XML or HTML responce
    */
   public function generateResponse() {
      $ret = '';
      if ($this->contentType == 'xml') {
         $ret = '<?xml version="1.0" encoding="UTF-8"?><r>';
         foreach ( $this->elementsById as $key => $val ) {
            $ret .= '<h id="' . $key . '"><![CDATA[';
            $ret .= $val;
            $ret .= ']]></h>';
         }
         
         foreach ( $this->elementsByTagName as $key => $val ) {
            $ret .= '<h name="' . $key . '"><![CDATA[';
            $ret .= $val;
            $ret .= ']]></h>';
         }
         
         foreach ( $this->attributesByTagName as $key => $val ) {
            $ret .= '<h tag="' . str_replace ( '"', '\'', $key ) . '" attr="' . $val [0] . '"><![CDATA[';
            $ret .= $val [1];
            $ret .= ']]></h>';
         }
         foreach ( $this->jsEvals as $val ) {
            $ret .= '<e><![CDATA[';
            $ret .= $val;
            $ret .= ']]></e>';
         }
         $ret .= '</r>';
      } elseif ($this->contentType == 'html') {
         $tplContent = Templater::loadTemplate ();
         $html = str_get_html ( $tplContent );
         
         # insert html
         foreach ( $this->elementsById as $key => $val ) {
            $o=$html->getElementById($key);
            if(is_object($o))
               $o->innertext = $val;
         }
         
         foreach ( $this->elementsByTagName as $key => $val ) {
             $o=$html->getElementByTagName ( $key );
            if(is_object($o))
               $o->innertext = $val;
         }
         foreach ( $this->attributesByTagName as $key => $val ) {
            $el = $html->find ( $key, 0 );
            if(is_object($el))
               $el->setAttribute ( $val [0], $val [1] );
         
         }
         #insert JS
         $scriptBody = '';
         foreach ( $this->jsEvals as $val )
            $scriptBody .= "\n" . $val;
         $html->getElementByTagName ( 'head' )->innertext .= '<script type="text/javascript">' . "\n" . '$(document).ready( function() {' . "\n" . $scriptBody . '' . "\n" . '});' . "\n" . '</script>' . "\n";
         $ret = $html->save ();
      } elseif ($this->contentType == 'rss') {
         $ret = '<?xml version="1.0" encoding="UTF-8"?>';
         $ret .= '<rss version="2.0">';
         $ret .= $this->generateRssResponceFromArray ( $this->elementsById );
         $ret .= '</rss>';
      }
      if ($this->contentType != 'file') {
         header ( "Content-Type:" . $this->contentTypeArray [$this->contentType] );
         return $ret;
      }
   }
   
   public function testGenerateRssResponceFromArray($array) {
      return $this->generateRssResponceFromArray ( $array );
   }
   
   private function generateRssResponceFromArray($array) {
      $ret = '';
      foreach ( $array as $key => $val ) {
         
         if (! is_array ( $val )) {
            if ($key == 'description')
               $ret .= '<' . $key . '><![CDATA[' . stripslashes ( $val ) . ']]></' . $key . '>';
            else
               $ret .= '<' . $key . '>' . htmlspecialchars ( $val ) . '</' . $key . '>';
         } elseif (! is_integer ( $key ))
            $ret .= '<' . $key . '>' . $this->generateRssResponceFromArray ( $val ) . '</' . $key . '>';
         else
            $ret .= $this->generateRssResponceFromArray ( $val );
      
      }
      return $ret;
   }
   public function __toString() {
      $ret = "\n";
      foreach ( $this->elementsById as $key => $val )
         $ret .= '[' . $key . ']=' . $val . "\n\t";
      
      $ret .= "\n";
      return $ret;
   }
}

?>